package com.other.server;


import com.other.util.CloseUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class Request {
    private String method;
    private String url;

    private Map<String,List<String>> parameterMapValues;

    private InputStream in;
    private String requestInfo;
    public static final String CRLF="\r\n";
    public static final String BLANK=" ";

    private Request() {
        this.method = "";
        this.url = "";
        this.parameterMapValues=new HashMap<>();
    }

    public Request(InputStream in) {
        this();
        this.in= in;

        try {
            byte[] dates = new byte[20480];
            int len = 0;
            len = in.read(dates);
            requestInfo = new String(dates,0,len);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        parseRequestInfo();
    }

    /**
     * 分析请求信息
     */
    public void parseRequestInfo(){
        if(requestInfo == null||requestInfo.trim().equals("")){
            return;
        }
        /**
         * =====================================
         * 从信息的首行分解出 :请求方式    请求路径   请求参数(get可能存在)
         *   如:GET /index.html?name=123&pwd=5456 HTTP/1.1
         *
         * 如果为post方式，请求参数可能在 最后正文中
         *
         * 思路:
         * 1)请求方式 :找出第一个/  截取即可
         * 2)请求资源:找出第一个/   HTTP/
         * =====================================
         */
        String paramString =""; //接收请求参数

        //1、获取请求方式
        String firstLine =requestInfo.substring(0,requestInfo.indexOf(CRLF));
        int idx =requestInfo.indexOf("/"); // /的位置
        this.method=firstLine.substring(0, idx).trim();
        String urlStr =firstLine.substring(idx,firstLine.indexOf("HTTP/")).trim();
        if(this.method.equalsIgnoreCase("post")){
            this.url=urlStr;
            paramString=requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();

        }else if(this.method.equalsIgnoreCase("get")){
            if(urlStr.contains("?")){ //是否存在参数
                String[] urlArray=urlStr.split("\\?");
                this.url=urlArray[0];
                paramString=urlArray[1];//接收请求参数
            }else{
                this.url=urlStr;
            }
        }


        //不存在请求参数
        if(paramString.equals("")){
            return ;
        }
        //2、将请求参数封装到Map中
        parseParams(paramString);
    }
    private void parseParams(String paramString){
        //分割 将字符串转成数组
        StringTokenizer token=new StringTokenizer(paramString,"&");
        while(token.hasMoreTokens()){
            String keyValue =token.nextToken();
            String[] keyValues=keyValue.split("=");
            if(keyValues.length==1){
                keyValues = Arrays.copyOf(keyValues, 2);
                keyValues[1] =null;
            }

            String key = keyValues[0].trim();
            String value = null==keyValues[1]?null:decode(keyValues[1].trim(),"utf-8");
            //转换成Map 分拣
            if(!parameterMapValues.containsKey(key)){
                parameterMapValues.put(key,new ArrayList<String>());
            }

            List<String> values =parameterMapValues.get(key);
            values.add(value);
        }

    }

    /**
     * 解决中文
     * @param value
     * @param code
     * @return
     */
    private String decode(String value,String code){
        try {
            return java.net.URLDecoder.decode(value, code);
        } catch (UnsupportedEncodingException e) {
            //e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据页面的name 获取对应的多个值
     */
    public String[] getParameterValues(String name){
        List<String> values=null;
        if((values=parameterMapValues.get(name))==null){
            return null;
        }else{
            return values.toArray(new String[0]);
        }
    }
    public Map<String, List<String>> getParameterMapValues() {
        return parameterMapValues;
    }
    public String getUrl() {
        return url;
    }

    public String getMethod() {
        return method;
    }

    public void close(){
        CloseUtil.closeIO(in);
    }
}
